预处理指令：
	在C语言中以#开头的语句都叫做预处理指令，因为这些不是标准的C代码，不能被编译器直接编译，
	需要一段程序把它翻译成标准的C代码，负责翻译在程序叫预处理器，翻译的过程叫预处理。
	
	gcc -E code.c 把预处理的结果显示在终端上。
	gcc -E code.c -o code.i 把预处理的结果存储到文件中。
		-o 为执行结果重命名
	
	1、文件包含 
		#include<> 从系统指定的路径加载头文件
		#include"" 先从当前路径加载头文件，如果没有再从系统指定的路径加载头文件。
		操作系统通过设置环境变量来指定加载头文件的路径
		-I路径 编译时指定加载头文件的路径
	
	2、头文件卫士,防止头文件被重复包含
		#ifndef FILE_H
		#define FILE_H
		......
		#endif//FILE_H
		a.h b.h c.h
		b.h 包含 a.h c.h包含a.h再包含b.h 这样a.h中的内存在c.h中就有了两人份，在而头文件卫士可以解决这种问题。
		注意：头文件卫士不能解决循环包含的问题(a.h包含b.h,而b.h又包含a.h)，解决方法是把a.h和b.h共用的内存提出来再写一个c.h，然后a.h和b.h都包含c.h。
	
	3、宏定义
		
		单纯宏 #define NAME 可以配合头文件卫士，条件编译使用。
		
		宏常量 #define  PI 3.14 
			预处理器会把代码中的所有宏名替换成它后面的数字。
			好处：
				1、比用变量安全性高。
				2、比直接使用数据的扩展性强。
				3、可以为数据取一个有意义的名字，提高可读性。
			注意：定义宏时不带分号，一般宏名都全部大定。
		
		
		常见笔试题：定义宏表示一年有多少秒
				#define YEAR_SEC (365*24*3600UL)
		
		
		宏函数 #define SUM(a,b) a+b+b+a
			带参数的宏，并不是真正的函数，只是使用样式与函数一样。
			其实就把一个复杂的公式抽象成一个像函数一样的宏。
			如果宏函数的内容太长可以使用大括号，但不能换行（可以使用续行符\）。
			优点：
				1、方便使用。
				2、速度快（没有进行参数传递、压栈、出栈、释放栈的过程）。
				3、类型通用，只有极精简的代码段才使用
			缺点：
				1、不会对参数进行类型检查，安全性差。
				2、没有返回值，只用一个运算结果，因此处理不了很复杂的业务逻辑。
				3、过多使用会增加代码段人冗余。
			注意：二义性，调用宏函数时不要使用自变运算符。
			
			练习1：实现swap功能的宏，要求任何类型都能使用。
				在编译再定义宏：gcc -D PI=3.14
		
		预定义的宏：
			__DATE__	//日期		
			__TIME__	//时间
			__func__			
			__FUNCTION__//函数名
			__FILENAME__//文件名
			__LINE__	//行号
	4、条件编译
		#if/#elif/#else/#endif  #ifndef #ifdef
		C语言中的if/else是根据条件决定代码是否执行。
		而预处理的#if#else根据条件决定代码是否生成，这样可以减小代码段。
		#if 0 #endif可以对代码进行注释。
		// 不通用
		/* 不能嵌套 */
		
